package libtool65.cmd;

import java.io.FileOutputStream;
import java.io.IOException;

import libtool65.link.Linker;
import libtool65.o65.Module;
import libtool65.o65.Reader;

public class LinkCommand  extends LinkerBase {
	Option base_option = new Option(true);
	Option raw_option = new Option(true);
	Option prg_option = new Option(true);
	Option zpbase_option = new Option(true);

	@Override
	public Option addOption(String option_string) {
		if (option_string.equals("--base"))
			return base_option;
		if (option_string.equals("--zpbase"))
			return zpbase_option;
		if (option_string.equals("--raw"))
			return raw_option;
		if (option_string.equals("--prg"))
			return prg_option;
		return super.addOption(option_string);
	}

	@Override
	public void execute() throws Exception {
		Reader reader = new Reader();
		Linker linker = new Linker();
		for (String file : parameters)
		{
			Module module = readModule(reader, file);
			if (module != null)
				linker.add(file, module);
		}
		if (linker.hasUnresolvedReferences())
		{
			System.out.println("Unresolved references:");
			for (String unref : linker.getUnresolvedReferences())
			{
				System.out.println("  "+unref);
			}
		}
		else
		{
			linker.link(base_option.getAddress(), zpbase_option.getAddress());
			if (raw_option.isPresent())
			{
				writeBinary(linker, false, raw_option.getText());
			}
			if (prg_option.isPresent())
			{
				writeBinary(linker, true, prg_option.getText());
			}
		}
	}

	public void writeBinary(Linker linker, boolean write_address_first,
			String file_name) {
		FileOutputStream outfile = null;
		try
		{
			outfile = new FileOutputStream(file_name);
			linker.writeBinary(outfile, write_address_first);
		}
		catch (IOException e)
		{
			System.out.println("File write failed for \""+file_name+"\": "+e.getMessage());
		}
		finally
		{
			if (outfile != null)
				try { outfile.close(); } catch (IOException e) {}
		}
	}

	@Override
	public void printHelp() {
		System.out.println("Links modules for a fixed address");
		System.out.println("Parameters:");
		System.out.println("   --base <address>		   ... code base adress");
		System.out.println("   --zpbase <address>      ... zero page base adress");
		System.out.println("   --raw <file name>       ... raw output file name");
		System.out.println("   --prg <prg file name>   ... prg output file name");
	}
}
